import React from 'react';
import ReactDOM from 'react-dom';
import { log } from '@/utils/log-utils';
import styles from '@/pages/review/index.less';
import { Toast, ListView, NavBar, Icon} from 'antd-mobile';
import { Col, Row } from 'antd';
import { btnSound, playSound } from '@/utils/sounds-res';
import ReviewBoard from '@/pages/review/board';
import { noDataImg } from '@/utils/images-res';
import SocketEvent from '@/service/event';
import AdvancedBtn from "@/button";
import AdvancedSpin from "@/spinner";

/**
 * 复盘平台
 */
class ReviewPlatform extends React.Component {

  constructor(props) {
    super(props);
    this.reviewList = 'reviewList';
    this.reviewBoard = 'reviewBoard';

    // ListView数据对象
    const dataSource = new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    });

    this.state = {
      loading: false,
      text: null,
      data: [],
      listviewLoading: false,
      dataSource: dataSource,
      pageNum: 1,
      pageSize: 10,
      dataTotal: 1,
      pageView: this.reviewList,
      // 复盘的数据
      reviewData: { battleData: {}, stepData: [] },
      // listview 的高度(自适应)
      listViewHeight: 0,
      // listview 每行数据的高度
      listLineHeight: 0,
      // 滚动条距离顶部的值
      scrollTop: 0,
      // 滚动条是否在滚动
      isScroll: true,
    };
  }

  componentDidMount() {
    this.queryDataList();
    // 设置listview高度
    setTimeout(() => {
      const bodyHeight = document.documentElement.clientHeight;
      const navBarHeight = ReactDOM.findDOMNode(this.navBarRef).clientHeight;
      this.setState({ listViewHeight: bodyHeight - navBarHeight });
    }, 10)

    // 滚动条滚动暂时事件
    this.handleScrollStop();
  }

  /**
   * 处理滚动条停止事件
   */
  handleScrollStop = () => {
    let historyScrollTop = 0;
    setInterval(() => {
      const scrollTop = this.state.scrollTop;
      if(this.state.isScroll && historyScrollTop === scrollTop) {
        this.setState({ isScroll: false })
      }
      historyScrollTop = scrollTop;
    }, 3 * 1000)
  }

  queryDataList = () => {
    const { userId, socket } = this.props;
    const { pageNum, pageSize, dataSource, data } = this.state;
    this.setState({ listviewLoading: true });

    log(`开始获取复盘数据列表, userId: ${userId} pageNum: ${pageNum} pageSize: ${pageSize}`);
    SocketEvent.emit(socket,'battleReviewApi', {
      userId: userId,
      pageNum: pageNum,
      pageSize: pageSize,
    }, resp => {
      log(`复盘数据列表resp: `, resp);
      this.setState({ loading: false });
      if (resp.code === 'success') {
        const { list, dataTotal } = resp.data;
        data.push(...list);
        this.setState({
          data: data,
          dataTotal,
          dataSource: dataSource.cloneWithRows({...data}),
          listviewLoading: false,
          pageNum: pageNum + 1,
        });
      } else {
        Toast.show(resp.msg);
      }
    });
  };

  /**
   * 离开复盘列表
   */
  handleLeaveReviewList = () => {
    playSound(btnSound);
    const { userId, socket } = this.props;
    SocketEvent.emit(socket,'leaveReviewListApi',{
      userId: userId,
    }, resp => {
      log('离开复盘列表, resp: ', resp);
      if(resp.code === 'success') {
        this.props.goBack();
      } else {
        Toast.show(resp.msg);
      }
    })
  };


  /**
   * 加载已选择的对局数据
   * @param e
   * @param columnData
   */
  selectedBattle = (e, columnData) => {
    playSound(btnSound);
    const { userId } = this.props;
    const { pageSize } = this.state;
    const { battleId } = columnData;
    log(`用户[${userId}]开始请求对战区[${battleId}]复盘数据`);

    SocketEvent.emit(this.props.socket,'battleReviewDetailApi', {
      userId: userId,
      battleId: battleId,
      pageSize: pageSize,
    }, resp => {
      log(`查询复盘详情的resp：`, resp);
      this.setState({ loading: false });
      if (resp.code === 'success') {
        this.setState({
          pageView: this.reviewBoard,
          reviewData: {
            battleData: columnData,
            stepData: resp.data,
          },
        });
      } else {
        Toast.show(resp.msg);
      }
    });
  };

  /**
   * 查复盘列表的视图
   */
  reviewListView = () => {
    const { data, pageNum, dataTotal, pageSize } = this.state;
    return (
      <div className={styles.watch}>
        <div className={styles.title}>
          <div title={'icon'}/>
          <span>棋局列表</span>
        </div>

        <div className={styles.content}>
          <div className={styles.list} ref={ref => this.scrollRef = ref}>
            {
              data.map((item, index) => {
                return (
                  <Row key={item.battleId} className={styles.row} onClick={e => this.selectedBattle(e, item)}>
                    <Col span={2} className={styles.colTitle}>{(index + 1)}.</Col>
                    <Col span={7} className={styles.colContent}>{item.firstUserName}</Col>
                    <Col span={2} className={styles.colTitle}>:</Col>
                    <Col span={7} className={styles.colContent}>{item.lastUserName}</Col>
                    <Col span={6}
                         className={styles.colTitle}
                         style={{ color: `${item.resultMsg === '失败' ? '#f30404de' : '#ffb200'}` }}>
                      {item.resultMsg}(<span>{String(item.changeScore).startsWith("-") ? '' : '+'}{item.changeScore}</span>)
                    </Col>
                  </Row>
                );
              })
            }
            {/*空数据集展示*/}
            {
              (data.length === 0) &&
              <div className={styles.refresh}>
                <img src={noDataImg} alt={''} />
                <span>暂无数据</span>
              </div>
            }
          </div>
          <div className={styles.floor}>
            <Row>
              <Col span={7}>
                <AdvancedBtn
                  type="normal"
                  text="上页"
                  disabled={pageNum === 1}
                  onClick={async e => {
                    playSound(btnSound);
                    if(pageNum === 1) {
                      Toast.show('已达第一页')
                    } else {
                      await this.setState({ pageNum: pageNum - 1 });
                      this.scrollRef.scrollTop = 0;
                      this.queryDataList();
                    }
                  }}
                />
              </Col>
              <Col span={1}/>
              <Col span={7}>
                <AdvancedBtn
                  type="normal"
                  text="下页"
                  disabled={(pageNum * pageSize) >= dataTotal}
                  onClick={async e => {
                    playSound(btnSound);
                    if((pageNum * pageSize) >= dataTotal) {
                      Toast.show('已达最后一页');
                    } else {
                      await this.setState({ pageNum: pageNum + 1 });
                      this.scrollRef.scrollTop = 0;
                      this.queryDataList();
                    }
                  }}
                />
              </Col>
              <Col span={1}/>
              <Col span={8}>
                <AdvancedBtn type="danger" text="离开" onClick={e => this.handleLeaveReviewList(e)} />
              </Col>
            </Row>
          </div>
        </div>
        <AdvancedSpin text={this.state.text} show={this.state.loading}/>
      </div>
    );
  };


  reviewListViewPlus = () => {
    const { data, listviewLoading, dataSource, pageView, listViewHeight, scrollTop, isScroll, pageSize, dataTotal } = this.state;
    const rowView = (item, sectionID, rowId) => {
      // px
      const marginSize = 4;
      return (
        <div key={rowId}
             className={styles.rowBody}
             style={{height: `${listViewHeight / pageSize - marginSize}px`, margin: `${marginSize}px 0`}}
             onClick={e => this.selectedBattle(e, item)}>
          <div className={styles.serial}>
            {Number(rowId) + 1}.
          </div>
          <div className={styles.left}>
            <div className={styles.oneLine}>
              <span>{item.firstUserName}</span>
              <span>:</span>
              <span>{item.lastUserName}</span>
            </div>
            <div className={styles.twoLine}>
              <span>{item.createTime}</span>
              <span>{item.winCodeName}</span>
            </div>
          </div>
          <div className={styles.right}>
            <div
              className={styles.result}
              style={{color: `${item.resultMsg === '失败' ? '#f30404' : 'rgb(255, 255, 0)'}`}}>
              {item.resultMsg}
            </div>
            <div
              className={styles.score}
              style={{color: `${item.resultMsg === '失败' ? '#f30404' : 'rgb(255, 255, 0)'}`}}>
              <span>{String(item.changeScore).startsWith("-") ? '' : '+'}{item.changeScore}</span>
            </div>
          </div>
        </div>
      );
    };

    return (
      <div className={styles.watchPlus} hidden={!(pageView === this.reviewList)}>
        <NavBar
          ref={ref => this.navBarRef = ref}
          className={styles.title}
          mode="light"
          icon={<Icon type="left" />}
          onLeftClick={() => this.handleLeaveReviewList()}
          rightContent={[
            <Icon key="1" type="ellipsis"/>,
          ]}
        >棋局列表</NavBar>
        <ListView
          ref={el => this.lv = el}
          dataSource={dataSource}
          // 从数据源(data source)中接受一条数据，以及它和它所在section的ID。返回一个可渲染的组件来为这行数据进行渲染
          renderRow={rowView}
          // 在线行末尾添加内容
          // renderSeparator={separator}
          // 页脚
          renderFooter={() => (
            (data.length > 0 || listviewLoading)
              ? <div className={styles.listviewLoad}>
                {listviewLoading ? '正在请求数据' : '~ 我也是有底线的 ~'}
              </div>
              : <div className={styles.emptyData}>
                <img src={noDataImg} alt={''} />
                <span>暂无数据</span>
              </div>
          )}
          // 每次事件循环（每帧）渲染的行数
          pageSize={this.state.pageSize}
          initialListSize={this.state.pageSize}
          onScroll={e => { this.setState({ scrollTop: e.target.scrollTop, isScroll: true }); }}
          // 当一个行接近屏幕范围多少像素之内的时候，就开始渲染这一行
          scrollRenderAheadDistance={500}
          // 当所有的数据都已经渲染过，并且列表被滚动到距离最底部不足onEndReachedThreshold个像素的距离时调用
          onEndReached={e => this.queryDataList()}
          onEndReachedThreshold={500}
          style={{
            height: listViewHeight,
            overflow: 'auto',
            // background: 'rgba(0, 0, 0, 0.2)',
            backdropFilter: 'blur(2px)',
            webkitBackdropFilter: 'blur(2px)',
          }}
        />
        <div className={styles.page} hidden={!isScroll}>
          <span>{Math.ceil(scrollTop / listViewHeight + 1)}</span>
          <div>&nbsp;</div>
          <span>{~~((dataTotal - 1) / pageSize) + 1}</span>
        </div>
      </div>
    );
  }

  render() {
    const { pageView } = this.state;
    return (
      <React.Fragment>
        {/*这个页面必须一直加载，如果不是当前页面的时候，就影响不然会导致列表重置*/}
        {this.reviewListViewPlus()}
        {
          (pageView === this.reviewBoard) &&
          <ReviewBoard
            reviewData={this.state.reviewData}
            socket={this.props.socket}
            userId={this.props.userId}
            goBack={() => this.setState({ pageView: this.reviewList })}
          />
        }
      </React.Fragment>
    );
  }
}

export default ReviewPlatform;


